/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package reflection.demo;

import java.lang.reflect.*;

/**
 *
 * @author VANDH reflection -> phản thân, nhìn chính mình
 */
public class ReflectionDemo {

    /*
     * Viết đoạn CT nhận vào một chuỗi, chuỗi này chứa tên class
     * hiển thị ra tên class, thông tin các field, method
     * constructor của class đó
     */
    public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//        Scanner keyboard = new Scanner(System.in);
//        String className = keyboard.nextLine();
//
//        Class classInfo = Class.forName(className);
//
//        System.out.println("Name : " + classInfo.getName()
//                + " - " + classInfo.getSimpleName());

//        getMethods(classInfo);
//        newInstance();

        // Nhập vô tên một kiểu dữ liệu, và 1 số nguyên
        // Tạo một mảng với kiểu đã cho, số lượng đã cho
        String elementType = "java.lang.String";
//        int length = 10;

//        Object a = Array.newInstance(Class.forName(elementType), length);
//        Array.set(a, 0, "Phan tu 0");
//        Array.set(a, 1, "Phan tu 1");
//        System.out.println(Array.get(a, 1));
        Class classInfo = Class.forName(elementType);
        listOfConstructor(classInfo);
    }

    private static void listOfConstructor(Class c) throws SecurityException, NoSuchMethodException {
        System.out.println("List of constructors : ");
        System.out.println("--------------------------------");
        // String (java.lang.StringBuilder)
        Constructor[] cc = c.getConstructors();
        // StringBuilder.class -> object Class chứa thông tin của StringBuilder
        for (int i = 0; i < cc.length; i++) {
            System.out.print("\t" + cc[i].getName());
            // Tạo chuỗi chứa danh sách tham số
            String paraList = "(";
            for (Class j : cc[i].getParameterTypes()) {
                paraList += j.getCanonicalName() + ",";
            }
            paraList += ")";
            System.out.println(paraList);
        }
        System.out.println("-------------------------");
        System.out.println(c.getConstructor(StringBuilder.class));
    }

    private static void getMethods(Class c) throws SecurityException, NoSuchMethodException {
        System.out.println("List of methods ");// + c.getMethod("indexOf", int.class));
        System.out.println("---------------------------------------");

        for (Method m : c.getMethods()) {
            System.out.println(m);
        }
    }

    private static void newInstance() throws InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, NoSuchMethodException, SecurityException {
        String className = "java.lang.String";
        Class c = Class.forName(className);
        Constructor cc = c.getConstructor(String.class);
        Object myString = cc.newInstance("abcd");
        String s = (String) myString;
        System.out.println("Length of string " + s.length());
        System.out.println("---------------------------------");

        String callMethod = "indexOf";
        //callMethod.indexOf("a");
        //"abc".indexOf("b");
        Method m = c.getMethod(callMethod, String.class);
        int index = (int) m.invoke(myString, "c");
        System.out.println(index);


//        System.out.println("Default constructor : " + c.getConstructor(Class.forName("[B")));
//        Constructor o = c.getConstructor(String.class);
//        Object n = o.newInstance("Hello test");
//        String methodName = "indexOf";
//        Method m = c.getMethod(methodName, String.class);
//        System.out.println((int) m.invoke(n, "test"));
    }
}
